﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsAPI.Windows
{
    public partial class Window
    {
        /* --------------------------------------------------------------------------------------------- */

        public static Window ForegroundWindow
        {
            get { return new Window(User32.GetForegroundWindow()); }
            set { if(value != null) value.SetForeground(); }
        }

        public static Window GetWindow(string ClassName, string Title)
        {
            var hWnd = User32.FindWindow(ClassName, Title);
            return hWnd == IntPtr.Zero ? null : new Window(hWnd);
        }

        public static Window Desktop { get { return new Window(User32.GetDesktopWindow()); } }

        public static ProgmanWindow Progman { get { return ProgmanWindow.Get(); } }

        /// <summary>Получить окно в системе по заголовку</summary>
        /// <param name="Title">Заголовок окна</param>
        /// <returns>ОКно с указанным заголовком, если оно существует</returns>
        //[ExportDllAttribute.ExportDll("ExportNameOfFunction", System.Runtime.InteropServices.CallingConvention.Cdecl)]
        public static Window GetWindow(string Title) { return GetWindow(null, Title); }

        public static Window GetWindow(int X, int Y) { return GetWindow(new Point(X, Y)); }
        public static Window GetWindow(Point Location)
        {
            var hWnd = User32.WindowFromPoint(Location);
            return hWnd == IntPtr.Zero ? null : new Window(hWnd);
        }

        public static Window[] FindWindow(Predicate<Window> selector)
        {
            var result = new List<Window>();
            EnumWindowProc proc = (hWnd, lParams) =>
            {
                var window = new Window(hWnd);
                if(selector(window))
                    result.Add(window);
                return true;
            };
            User32.EnumWindows(proc, IntPtr.Zero);

            return result.ToArray();
        }

        /* --------------------------------------------------------------------------------------------- */

        public static implicit operator IntPtr(Window window) { return window.Handle; }

        public static implicit operator Window(IntPtr hWnd) { return new Window(hWnd); }

        public static implicit operator Window(Form form) { return new Window(form); }

        public static bool operator ==(Window W1, Window W2)
        {
            return ReferenceEquals(W1, null) && ReferenceEquals(W2, null)
                   || !ReferenceEquals(W1, null) && W1.Equals(W2);
        }

        public static bool operator !=(Window W1, Window W2) { return !(W1 == W2); }

        /* --------------------------------------------------------------------------------------------- */
    }
}
